\chapter{User Interface (UI) \label{interface}}

Users interface with Aspen through three mechanisms: the command line,
configuration files, and the environment. Where a program parameter is set in
more than one of these contexts, they take precedence in the order given here.
For example, a \var{mode} option on the command line will override any
\var{mode} setting in a config file or in the environment.


\section{Command Line \label{command-line}}

Usage:

\begin{verbatim}
aspen [options] [command]
\end{verbatim}

Aspen takes one optional positional argument, \var{command}, which must be one
of: \code{start}, \code{status}, \code{stop}, \code{restart}, or \code{runfg}.
The default is \code{runfg}, which causes Aspen to run in the foreground,
sending all messages to stdout.

\code{start}, \code{status}, \code{stop}, and \code{restart} control Aspen as a
daemon, via a pidfile. If the website root has a directory named \file{__}
(that's two underscores; the \dfn{magic directory}), then the pidfile is at
\file{__/var/aspen.pid}. Otherwise, the pidfile is created in \file{/tmp}. When
run as a daemon, stdout and stderr are redirected to \file{__/var/aspen.log} if
\file{__} exists, and to \file{/dev/null} otherwise. The \file{__/var} directory
will be created if it does not exist. The permission mode of the pidfile is set
to \code{0600}; likewise with the logfile, unless it is \file{/dev/null}.

The Aspen distribution includes a script in \file{etc/aspen_bash_completion}
that can be used to configure the bash shell to autocomplete from among Aspen's
arguments. See the source for more information.

Aspen's command-line options are as follows:

\begin{tableiii}{l|l|l}{var}{Option}{Description}{Default}

\lineiii{\programopt{-a}/\longprogramopt{-address}=\var{address}}
    {The address to which Aspen should bind. If \var{address} begins with a dot
    or a forward slash, then it is interpreted as an AF_UNIX socket. If it
    contains more than one colon, it is seen as an AF_INET6 address. Otherwise,
    it is interpreted as AF_INET. If \var{address} begins with a colon, the IP
    address defaults to \code{0.0.0.0}.} {\code{0.0.0.0:8080}}

\lineiii{\programopt{-m}/\longprogramopt{-mode}=\var{mode}}
    {One of \code{debugging}, \code{development}, \code{staging}, or
    \code{production}. In debugging and development modes, Aspen will restart
    itself any time configuration files or module source files change on the
    filesystem.}
    {\code{development}}

\lineiii{\programopt{-r}/\longprogramopt{-root}=\var{root}}
    {The directory containing the website for Aspen to serve.}
    {\code{.}}

\end{tableiii}


\section{Configuration Files \label{config-files}}

Aspen obeys several configuration files, all located in \file{__/etc}. The
comment character for these files is \#, and comments can be included in-line.
Blank lines are ignored, as is initial and trailing whitespace per-line. Where
section names are called for, they are given in brackets.

Where a configuration file calls for a Python object to be specified, this is
done in a notation derived from setuptools' entry_points feature: a dotted
module name, followed by a colon and a dotted identifier naming an object within
the module. This is referred to below as \dfn{colon notation}. The following
example would import the \code{bar} object from \code{example.package.foo}, and
use its \code{baz} attribute:

\begin{verbatim}
example.package.foo:bar.baz
\end{verbatim}




\subsection{apps.conf}
\label{apps-conf}

In Aspen, an \dfn{application} or \dfn{app} refers to a WSGI application that is
connected to a particular directory. Apps are set up in \file{__/etc/apps.conf}.

The \file{__/etc/apps.conf} file contains a newline-separated list of
white-space-separated path name/object name pairs. The path names refer to
URL-space, and are translated literally to the filesystem. If the trailing slash
is given, then requests for that directory will first be redirected to the
trailing slash before being handed off to the application. If no trailing slash
is given, the application will also get requests without the slash. When
choosing an application to service a request, the most specific pathname matches
first.

Object names are in colon notation, and they name WSGI callables. Aspen updates
the \code{SCRIPT_NAME} and \code{PATH_INFO} settings in \code{environ} before
handing off to the relevant callable. \code{SCRIPT_NAME} will never end with a
slash, and if \code{PATH_INFO} is not empty, it will always begin with a slash.

Aspen will (over)write a file called \file{README.aspen} in each directory
mentioned in \file{apps.conf}, containing the relevant line from
\file{apps.conf}. If the directory does not exist, it is created. Aspen will
also remove any obsolete \file{README.aspen} files within your site tree.


\subsubsection{Example apps.conf}

\begin{verbatim}
/foo        example.apps:foo    # will get both /foo and /foo/
/bar/       example.apps:bar    # /bar will redirect to /bar/
/bar/baz    example.apps:baz    # will 'steal' some of /bar's requests
\end{verbatim}


\subsection{aspen.conf}
\label{aspen-conf}

Aspen's general configuration file is at \file{__/etc/aspen.conf}. It is in
\file{.ini}-style format per the \module{ConfigParser} module. Aspen responds to
the following settings in the \code{main} section. You may define additional
settings and sections that are meaningful to your application, which you may
access using the \class{aspen.conf} object described below in the "API" chapter.

% There are five sections recognized: \code{DEFAULT},
% \code{debugging}, \code{development}, \code{staging}, and \code{production}. Any
% of the below settings can be given in any section, except for \var{mode}, which
% can only occur in \code{DEFAULT}. However, only two sections will be used at any
% given time: \code{DEFAULT}, and the section corresponding to the current
% deployment mode (see The Environment for more on mode).

\begin{tableiii}{l|l|l}{var}{Option}{Description}{Default}

\lineiii{address}{The address to which Aspen should bind. If \var{address}
begins with a dot or a forward slash, then it is interpreted as an AF_UNIX
socket. If it contains more than one colon, it is seen as an AF_INET6 address.
Otherwise, it is interpreted as AF_INET. If \var{address} begins with a colon,
the IP address defaults to \code{0.0.0.0}.}{\code{0.0.0.0:8080}}

\lineiii{defaults}{A comma-separated list of names to look for when a directory
is requested. Any default resource is located immediately before dispatching to
a handler.}{\code{index.html, index.htm}}

\lineiii{http_version}{The version of HTTP to speak, either \code{1.0} or
\code{1.1}.}{\code{1.1}}

% \lineiii{group}{A groupname or gid to which, if given, Aspen will attempt to
% switch after binding to the socket.}{}
%
% \lineiii{log_access}{Whether or not to maintain an access log. Valid options
% are (case-insensitive): \code{yes}, \code{no}, \code{none}, \code{true},
% \code{false}, \code{0}, \code{1}. The access log will be in Apache's Combined
% Log Format.}{\code{no}}
%
% \lineiii{log_format}{The format of error log messages, per the logging
% module.}{\code{\%(levelname)s:\%(name)s:\%(message)s}}
%
% \lineiii{log_level}{The error log level. Valid options per the logging module
% are (case-insensitive): \code{notset}, \code{debug}, \code{info},
% \code{warning}, \code{error}, \code{critical}.}{\code{warning}}
%
% \lineiii{log_filter}{A subsystem filter to apply to the error log, per the
% logging module.}{}

\lineiii{mode}{One of \code{debugging}, \code{development}, \code{staging}, or
\code{production}. In debugging and development modes, Aspen will restart itself
any time configuration files or module source files change on the
filesystem.}{\code{development}}
% (Naturally, this option only obtains in the DEFAULT section.)

\lineiii{threads}{The number of threads to maintain in the request-servicing
thread pool.}{\code{10}}

% \lineiii{user}{A username or uid to which, if given, Aspen will attempt to
% switch after binding to the socket.}{}
%
\end{tableiii}

\subsubsection{Example}

Here is an example \file{aspen.conf} configuration file:

\begin{verbatim}
[main]
address = :8000

[myapp]
knob = true
\end{verbatim}


\subsection{handlers.conf}
\label{handlers-conf}

Aspen \dfn{handlers} are WSGI applications that are associated with files and
directories on the filesystem according to arbitrary rules. This provides a
flexible infrastructure for many different development patterns.

The \file{__/etc/handlers.conf} file begins with an anonymous "rules" section,
which is a newline-separated list of white-space-separated rule name/object name
pairs. Rule names can be any string without whitespace. Each object name (in
colon notation) specifies a \dfn{rule}, a callable taking a filesystem path name
and an arbitrary predicate string, and returning \class{True} or \class{False}.
The path argument is absolute and is guaranteed to exist; it is
\envvar{PATH_TRANSLATED} from the WSGI environment, with any default resource
already located.

Following the rule specification are sections specifying \dfn{handlers}, which
as mentioned above are WSGI callables.

The name of each section specifies a handler (a WSGI callable) in colon
notation. The body of each section is a newline-separated list of conditions
under which this handler is to be called. Fundamentally, these conditions are
made up of a rule name as defined at the beginning of the file, and an arbitrary
predicate string (which can include whitespace) that is meaningful to the
matching rule callable. If no predicate is given, then the rule callable will
receive \class{None} for its predicate argument. Rules must be explicitly
specified at the beginning of the file before being available within handler
sections. After the first condition in a handler section, additional condition
lines must begin with one of \code{AND}, \code{OR}, or \code{NOT}. These
case-insensitive tokens specify how conditions are to be combined in evaluating
whether to use this handler.

On each request, handlers are considered in the order given, and the first
matching handler is used. Only one handler is used for any given request.

Note that if the file \file{__/etc/handlers.conf} exists at all, the defaults
(see the example below) disappear, and you must respecify any of the default
rules in your own file if you want them.


\subsubsection{Example handlers.conf}
This is Aspen's default handler configuration:

\begin{verbatim}
catch_all   aspen.rules:catch_all

[aspen.handlers.static:wsgi]
  catch_all
\end{verbatim}


Here is a more full-featured example:

\begin{verbatim}
catch_all   aspen.rules:catch_all
isfile      aspen.rules:isfile
fnmatch     aspen.rules:fnmatch


# Set up scripts.
# ===============

[aspen.handlers.simplates:stdlib]
    isfile
AND fnmatch *.html


# Everything else is served statically.
# =====================================

[aspen.handlers.static:wsgi]
  catch_all
\end{verbatim}

\subsection{logging.conf}
\label{logging-conf}

Aspen uses the Python \module{logging} library. You can configure logging with
a \file{__/etc/logging.conf} file, which is processed by the logging library's
\code{fileConfig} routine. If there is no \file{logging.conf} file, then Aspen
logs all messages to \file{sys.stderr}. Note that you are responsible to create
any directories needed to store log files that you specify in
\file{logging.conf}; Aspen does not create those directories for you, and will
not work if they do not exist.


\subsubsection{Example logging.conf}

Below is an example logging configuration file that logs all messages to a file
at \file{/var/log/aspen.log}, rotating every night at midnight, keeping old
logs for six days. See more examples in
\ulink{the
Python \module{logging} documentation}{http://docs.python.org/library/logging.html#configuring-logging}.


\begin{verbatim}
[loggers]
keys=root,aspen

[handlers]
keys=handler

[formatters]
keys=formatter


[logger_root]
level=NOTSET
handlers=handler

[logger_aspen]
level=NOTSET
handlers=handler
propagate=0
qualname=aspen


[handler_handler]
class=handlers.TimedRotatingFileHandler
level=NOTSET
formatter=formatter
args=('/var/log/aspen.log', 'midnight', -1, 6)
     #filename, when, interval [ignored], backupCount


[formatter_formatter]
format=%(asctime)s %(name)s %(levelname)s %(message)s
datefmt=
class=logging.Formatter
\end{verbatim}

\begin{seealso}

\seelink{http://docs.python.org/library/logging.html}
{\code{logging}}{The documentation for the standard Python logging library.}

\end{seealso}


\subsection{middleware.conf}
\label{middleware-conf}

Aspen allows for a full WSGI middleware stack, configured via the
\file{__/etc/middleware.conf} file. This is simply a newline-separated list of
middleware factories in colon notation. Each factory (which may be a class
constructor or other callable) is called with exactly one positional argument,
the next middleware on the stack. The first-mentioned middleware will therefore
be the outer-most in the stack (i.e., closest to the browser).


\subsubsection{Example middleware.conf}

\begin{verbatim}
example.foo:bar # closest to browser
example.baz:buz # closest to your apps/handlers
\end{verbatim}


\section{The Environment}
\label{environment}

Aspen incorporates a \module{mode} module, which uses the \envvar{PYTHONMODE}
environment variable to model the application life-cycle through four deployment
modes: \code{debugging}, \code{development}, \code{staging}, and
\code{production}. This module is available to your applications at
\module{aspen.mode}, and its API is documented in the "API" chapter, below.

Aspen itself adapts to the current \envvar{PYTHONMODE}. In debugging and
development modes, Aspen will restart itself any time a configuration file or
module source file changes on the filesystem.
